// phalanx functions.hpp.cu header file

// Copyright (c) 2011 - 2011 Kohei Takahashi (Flast).
// Distributed under the MIT license. for more detail see COPYING.

// Redefinition std::complex (C++0x's)

#ifndef IG_PHALANX_MATH_COMPLEX_FUNCTIONS_HPP_CU_ONCE_
#define IG_PHALANX_MATH_COMPLEX_FUNCTIONS_HPP_CU_ONCE_

#include <phalanx/config.hpp.cu>

#include <cmath>

#include <device_functions.h>

#include <phalanx/math/complex/complex_fwd.hpp.cu>

namespace phalanx
{

namespace math
{

template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( true )
T
real( const complex< T > &x_ )
{ return x_.real(); }

template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( true )
T
imag( const complex< T > &x_ )
{ return x_.imag(); }

template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( true )
T
arg( const complex< T > &x_ )
{ return atan2( x_.imag(), x_.real() ); }

template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( true )
T
norm( const complex< T > &x_ )
{
    T r( x_.real() ), i( x_.imag() );
    return r * r + i * i;
}

template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( true )
T
abs( const complex< T > &x_ )
{ return sqrt( norm( x_ ) ); }

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
conj( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
proj( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
polar( const T &rho_, const T &theta_ = 0 );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
acos( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
asin( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
atan( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
acosh( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
asinh( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
atanh( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
cos( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
cosh( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
exp( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
log( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
log10( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
pow( const complex< T > &x_, const complex< T > &y_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
pow( const complex< T > &x_, const T &y_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
pow( const T &x_, const complex< T > &y_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
sin( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
sinh( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
sqrt( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
tan( const complex< T > &x_ );

// TODO: implement this
template < typename T >
PHALANX_CONFIG_DEFAULT_FUNCTION( false )
complex< T >
tanh( const complex< T > &x_ );

} // namespace math

} // namespace phalanx

#endif // IG_PHALANX_MATH_COMPLEX_FUNCTIONS_HPP_CU_ONCE_

